<template>
	<view class="root">
		<view v-if="loaded" :class="hasComment?'item-container':'item-margin-container'">
			<!-- 标题显示 -->
			<text class="item-title">{{blog.title}}</text>
			<!-- 文章内容显示 -->
			<text class="item-author">{{blog.user.nickName}}@{{blog.createTime}}</text>
			<rich-text :nodes="blog.content" class="item-desc"></rich-text>
			<!-- 图片显示 -->
			<image :src="blog.picture" mode="widthFix" class="item-focus"></image>
			<!-- 头像显示 -->
			<image :src="blog.user.avatar" mode="aspectFill" class="item-avatar"></image>
			<!-- 显示标签，标签就是文本 -->

			<view class="icon-container">
				<!-- <image src="/static/icons(1)/ic_good.png" class="icon"></image> -->
				<text :class="goodIds.indexOf(blog.id)>=0?'iconfont icon-nan ic-red':'iconfont icon-nan ic-gray' "
					@click.stop="changeGood(blog.id)"></text>
				<text class="icon-text">{{blog.good}}</text>
				<image src="/static/icons(1)/ic_comment.png" class="icon"></image>
				<text class="icon-text">{{blog.comments.length}}</text>
				<image src="/static/icons(1)/ic_count.png" class="icon"></image>
				<text class="icon-text">{{blog.readCount}}</text>
			</view>
			<!-- <image src="/static/icons(1)/ic_delete.png" class="icon-tag"></image> -->
			<text class="iconfont icon-tianranqi icon-tag" @click.stop="drop(item.id)"></text>
		</view>
		<view v-if="hasComment" class="item-container">
			<view v-for="(parent, index) in parents" :key="parent.id">
				<view class="cmt-container">
					<text class="cmt-author">{{ parent.nickName }}</text>
					<text class="cmt-time">{{ parent.createTime}}</text>
					<image :src="parent.avatar" mode="aspectFill" class="cmt-avatar"></image>
					<text class="cmt-content" @click="clickReply(parent)">{{parent.content}}</text>
				</view>
				<view v-if="replies[index].length>0" class="reply-container">
					<view v-for="(reply,idx) in replies[index]" class="reply-item" :key="reply.id">
						<view class="reply-info">
							<text class="reply-author">{{reply.nickName}}</text>
							<text class="reply-to">@{{reply.toUser}}</text>
							<text class="reply-time">{{reply.createTime}}</text>
						</view>
						<view class="reply-content" @click="clickReply(reply)">{{reply.content}}</view>
					</view>
				</view>

				<view v-if="index < parents.length -1" class="cmt-line"></view>
			</view>
		</view>
		<view class="input-container">
			<image :src="avatar" mode="aspectFill" class="input-avatar" @click.stop="showuser"></image>

			<!-- 	<image :src="avatar" mode="aspectFill" class="input-avatar"></image> -->
			<textarea auto-height :value="inputValue" :placeholder="inputHolder" @input="inputGetArea"
				class="input-area" placeholder-class="input-holder" />
			<text class="iconfont icon-nan input-commit" @click="clickCommit"></text>
		</view>
		<login-dialog ref="login" @login="afterLogin"> </login-dialog>
	</view>
</template>
<script>
	
	
	export default {
		data() {
			return {
				loading: false,
				goodIds: [],
				blog: {},
				loaded: false,
				parents: [],
				replies: [],
				hasComment: false,
				avatar: '../../static/icons/default_user.png',
				inputValue: '',
				inputHolder: '请输入评论内容...',
				parentId: null

			}
		},
		//在页面加载时获取本地存储中的 goodIds 数据，同时从页面跳转时传递的参数中获取 id，并调用 getBlog 方法来获取博客信息。
		onLoad(options) {




			// 从本地存储中同步获取数据
			// uni.getStorageSync 是 uni-app 提供的一个同步从本地存储获取数据的方法。
			// this.$params 一般是自定义的对象，用于存储项目中的各类参数。
			// this.$params.key_good_ids 表示本地存储里特定数据的键名。这行代码的作用是通过该键名从本地存储同步获取对应的数据，并将其赋值给变量 ids。

			let ids = uni.getStorageSync(this.$params.key_good_ids)

			// 检查获取到的数据是否存在
			// 此 if 语句用于检查 ids 变量是否有值。
			// 若 ids 存在值，就把该值赋给页面实例的 goodIds 属性，这样后续代码就能够使用这个数据了。
			if (ids) {
				// 若存在，将其赋值给页面实例的 goodIds 属性
				this.goodIds = ids
			}

			// 从页面加载参数中获取 id
			// options 是 onLoad 函数的参数，它包含了页面加载时传递的参数。
			// 这行代码从 options 对象里提取 id 参数，并将其赋值给变量 id。

			let id = options.id
			//console.log(id);
			// 调用 getBlog 方法，传入获取到的 id
			this.getBlog(id)
			this.$noti.add(this.$params.noti_login_status,this.afterLogin,this)
		},
		onUnload(){
			this.$noti.remove(this.$params.noti_login_status,this)
		},
		methods: {
			clickCommit() {
				let app = getApp()
				if (app.globalData.token.length == 0) {
					this.$refs.login.show()
					return
				}
				if (this.inputValue.length == 0) {
					uni.showToast({
						title: '请输入评论内容！',
						icon: 'fail'
					});
					return
				}
				let url = this.$params.host + this.$params.action_comment

				let data = {
					nick_name: app.globalData.nickName,
					avatar: '/' + app.globalData.avatar,
					email: app.globalData.email,
					content: this.inputValue,
					blog_id: this.blog.id,
					parent_id: this.parentId,
					token: app.globalData.token,
					is_owner: app.globalData.id == this.blog.user.id
				}
				uni.showLoading({
					title: '上传评论......',
					mask: false
				});
				this.$req.post(url, data, res => {
					//console.log(res);
					res = res.data
					let cmt = res.data
					let comments = this.blog.comments.concat(cmt);
					this.blog.comments = comments
					console.log(comments);
					this.formatComments(comments)
					this.hasComment = this.blog.comments.length > 0
					this.inputValue = ''
					this.parentId = null
					this.inputHolder = '请输入评论内容...'
					let pages = getCurrentPages()
					let prev = pages[pages.length - 2]
					prev.refreshComments(cmt)

				}, () => {
					uni.hideLoading()
				})
			},
			clickReply(reply) {
				this.parentId = reply.id
				this.inputHolder = '@' + reply.nickName
			},
			inputGetArea(e) {
				console.log(e);
				this.inputValue = e.detail.value
			},

			afterLogin() {
				this.avatar = this.$params.host + getApp().globalData.avatar
			},
			showuser() {
				this.$refs.login.show()
			},
			goLogin() {
				this.$refs.login.show()
			},
			//用于处理博客的点赞和取消点赞操作
			changeGood(id) {
				let good = true //代表当前是点赞还是取消点赞
				if (this.goodIds.indexOf(id) >= 0) {
					good = false
				}
				if (good) {
					//1.把当前blog的id保存到缓存， 2.把点赞数量+1发送到服务器
					this.goodIds = [...this.goodIds, id]
				} else {
					//1.把当前blog的id从缓存的id集合中删除， 2.把点赞数量-1发送到服务器
					let index = this.goodIds.indexOf(id)
					if (index >= 0) {
						//this.goodIds.splice(index, 1) splice靠循环
						//this.goodIds.shift shift删除第一个元素
						//this.goodIds.pop（） pop删除最后一个元素
						this.goodIds[index] = this.goodIds[this.goodIds.length - 1]
						this.goodIds.pop()
					}
				}
				uni.setStorageSync(this.$params.key_good_ids, this.goodIds) //将 data 存储在本地缓存中指定的 key 中，会覆盖掉原来该 key 对应的内容
				this.postGood(id, good)

			},
			//用于向服务器发送点赞或取消点赞请求
			postGood(id, good) {
				//uni.showLoading用于显示加载中的提示框，通常在发起网络请求等需要一定时间完成的操作时使用
				uni.showLoading({
					title: '点赞....',
					mask: false //用于控制是否显示透明遮罩层
				});
				let url = this.$params.host
				// this.$params 通常是一个存储了项目各种参数配置的对象。
				// this.$params.host 代表服务器的基础地址
				let action = good ? this.$params.action_good : this.$params.action_del_good
				// good 是一个布尔类型的变量，用于判断当前是点赞操作还是取消点赞操作。
				// this.$params.action_good 是点赞操作对应的接口路径，比如 /api/good。
				// this.$params.action_del_good 是取消点赞操作对应的接口路径，比如 /api/del_good。
				url += action //拼接完整的请求 URL
				let data = {
					"id": id
				}
				//在准备要发送给服务器的数据
				//this.$req.postQuery 是一个自定义的方法，用于发送 POST 请求
				this.$req.postQuery(url, data, res => {
					//请求成功的回调函数
					//console.log(res);
					this.blog.good = res.data.data
					this.$noti.post(this.$params.noti_change_good, {
						id: id,
						count: res.data.data
					})
				}, () => {
					// 请求失败的回调函数
					//uni.hideLoading用途是隐藏通过 uni.showLoading 显示的加载提示框
					uni.hideLoading()
				})
			},

			getBlog(id) {

				// this.$params 通常是一个自定义的对象，用于存储项目中的配置参数。
				// this.$params.host 代表服务器的主机地址。
				// this.$params.action_top_blogs 代表获取博客信息的接口路径。
				// id 是传入函数的博客唯一标识。
				// 这行代码将主机地址、接口路径和博客 id 拼接成一个完整的请求 URL。

				// 构建请求的 URL
				let url = this.$params.host + this.$params.action_top_blogs + id
				console.log(url);

				// 调用 this.$req 对象的 get 方法发送 GET 请求
				this.$req.get(url, res => {

					// 从响应结果中提取博客数据
					let blog = res.data.data

					// 设置当前页面的导航栏标题
					uni.setNavigationBarTitle({
						title: blog.user.nickName
					})
					//this.$req 是一个自定义的请求对象，它封装了发送 HTTP 请求的功能。
					// this.$req.get 方法用于发送 GET 请求，接收两个参数：请求的 URL 和一个回调函数。
					// 回调函数 res => { ... } 在请求成功返回响应后执行，res 是服务器返回的响应对象。

					console.log(blog);
					console.log('拼接后图片路径：', blog.picture);

					blog.picture = this.$params.host + blog.picture
					blog.user.avatar = this.$params.host + blog.user.avatar
					blog.createTime = this.$formatTime(new Date(blog.createTime))
					blog.updateTime = this.$formatTime(new Date(blog.updateTime))
					blog.content = blog.content.replace('https', 'http').replace(/\<img/gi,
						'<img class="rich-img" ')

					this.blog = blog
					this.formatComments(blog.comments)
					this.loaded = true
					this.addReadCount(id)
				})
			},
			addReadCount(id) {
				let url = this.$params.host + this.$params.action_read_count
				let data = {
					id: id
				}

				this.$req.postQuery(url, data, res => {
					//console.log(res)
					this.blog.readCount = res.data.data

					//第一种获取页面栈实例
					//更新首页
					//this.refreshPrevPage(id,res.data.data)

					let count = res.data.data
					this.$noti.post(this.$params.noti_refresh_count, {
						id,
						count
					})

				}, () => {
					//this.getBlog(id)
				})
			},



			//刷新上一页面

			refreshPrevPage(id, count) {
				let pages = getCurrentPages()
				let prev = pages[pages.length - 2]
				prev.refreshReadCount(id, count)
			},
			//格式化评论数据
			formatComments(comments) {
				if (comments.length == 0) {
					return
				}
				let parents = []
				comments.forEach(c => {
					if (!c.avatar?.startsWith('http')) {
						c.avatar = this.$params.host + (c.avatar?.startsWith('/') ? c.avatar : `/${c.avatar}`);
					}
					c.createTime = this.$formatTime(new Date(c.createTime))
					if (c.parentId == null) {
						parents.push(c)
					}
				})
				parents.sort(function(p1, p2) {
					return new Date(p2.createTime).getTime() - new Date(p1.createTime).getTime()
				})


				let replies = Array.from({
					length: parents.length
				}, () => [])
				let index = 0
				parents.forEach(p => {
					// let cmmts = []
					// cmmts = [...cmmts, ...this.findAllChildren(p,comments)]

					replies[index++] = this.findAllChildren(p, comments)

				})
				console.log(replies);
				this.parents = parents
				this.replies = replies
				this.hasComment = comments.length > 0
			},
			findAllChildren(parent, comments) {
				let result = []
				comments.forEach(c => {
					if (c.parentId == parent.id) {
						c.toUser = parent.nickName
						result.push(c)
						result = [...result, ...this.findAllChildren(c, comments)]
					}
				})
				return result
			}
		}
	}
</script>

<style>
	@import url("blog.css");
</style>